#include "stm32f10x.h"                  // Device header
#define MOVING_AVERAGE_SIZE 10
void My_ADC_Init()
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //开GPIOB时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE); //开ADC时钟
	RCC_ADCCLKConfig(RCC_PCLK2_Div6); //ADC六分频 ADCCLK = 72MHz / 6 = 12MHz
	/* 
		配置PB0的引脚模式
	*/
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN; //AIN是(模拟输入模式)就是ADC的专属模式
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
	/*
		 输入通道配置
	配置为:
		ADC1,写入通道为通道8,规则菜单的第一个位置,采样周期为55个采样周期
	*/
	
	
	/*
		结构体初始化ADC
	*/
	ADC_InitTypeDef ADC_InitStruct;
	ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;  //ADC的工作模式,这里选择为独立模式
	ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; //ADC的采集数据对齐,这里选择右对齐模式
	ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //ADC触达源,这里选择NONE就是软件触发
	ADC_InitStruct.ADC_ContinuousConvMode = DISABLE; //连续转换还是单次转换
	ADC_InitStruct.ADC_ScanConvMode = DISABLE; //扫描模式还是非扫描模式
	ADC_InitStruct.ADC_NbrOfChannel = 1; //指定在扫描模式下 用到几个通道
	ADC_Init(ADC1,&ADC_InitStruct);
	
	ADC_Cmd(ADC1,ENABLE); //使能ADC
	
	/*
		校准ADC
	*/
	ADC_ResetCalibration(ADC1); //准备校准
	while(ADC_GetResetCalibrationStatus(ADC1) == SET); //等待准备校准完成
	ADC_StartCalibration(ADC1); //开始校准
	while(ADC_GetCalibrationStatus(ADC1) == SET); //等待校准完毕
}

/*
	取十次数据的平均值
*/
uint16_t ADC_GetLightValue()
{
    static uint16_t values[MOVING_AVERAGE_SIZE];
    static uint8_t index = 0;
    uint32_t sum = 0;
	ADC_RegularChannelConfig(ADC1,ADC_Channel_8,1,ADC_SampleTime_55Cycles5);
    // 获取新的ADC值
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
    uint16_t newValue = ADC_GetConversionValue(ADC1);

    // 存储新值，更新滤波数组
    values[index] = newValue;
    index = (index + 1) % MOVING_AVERAGE_SIZE;

    // 计算滤波后的值
    for (int i = 0; i < MOVING_AVERAGE_SIZE; i++)
    {
        sum += values[i];
    }

    // 返回平均值
    return sum / MOVING_AVERAGE_SIZE;
}


/*
	计算流明值
*/
uint16_t GetLux()
{
	uint16_t Value = ADC_GetLightValue();
	return (uint16_t)(400000/395.0)-((1000/3950.0)*Value);
}

/*
	取十次数据的平均值
*/

uint16_t ADC_GetSoilValue()
{
	/*
		如果是连续扫描模式下
		ADC_SoftwareStartConvCmd(ADC1,ENABLE);可以放在初始化函数里,运行一次就行了
		同时while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC) == RESET);也不需要了,直接返回结果就行
	*/
	static uint16_t values[MOVING_AVERAGE_SIZE];
    static uint8_t index = 0;
    uint32_t sum = 0;
	ADC_RegularChannelConfig(ADC1,ADC_Channel_9,1,ADC_SampleTime_55Cycles5);
    // 获取新的ADC值
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
    uint16_t newValue = ADC_GetConversionValue(ADC1)>>2;

    // 存储新值，更新滤波数组
    values[index] = newValue;
    index = (index + 1) % MOVING_AVERAGE_SIZE;

    // 计算滤波后的值
    for (int i = 0; i < MOVING_AVERAGE_SIZE; i++)
    {
        sum += values[i];
    }

    // 返回平均值
    return sum / MOVING_AVERAGE_SIZE;
}

uint16_t GetSoilHumi()
{
	uint16_t Value = ADC_GetSoilValue();
	return (uint16_t)(101500/843.0)-((100/843.0)*Value);
}







